package classReflectDemo;

import org.apache.log4j.Logger;

import java.lang.reflect.Field;

/**
 * @author Ajie
 * @date 4/8/21
 * @function 反射 属性，解决 ContextThemeWrapper 中的 mResources
 *
 * todo 循环调用 getDeclaredFields，才能得到父类 属性。
 *  getFields 只能得到 public 属性。不能得到属性。
 *
 *  //把值拿出来，为了还原。
 *  Object o = field.get(activity);
 *  //修改。。。
 *
 *  //还原 为原来的值
 *  field.set(activity,o);
 *
 * Field mMessages = clazz.getField("mMessages");// 私有 属性 获取异常。java.lang.NoSuchFieldException
 * Field mMessages = clazz.getDeclaredField("mMessages");//正常，获取私有属性
 */
public class Reflect_Field {
    private static final Logger logger = Logger.getLogger(Reflect_Field.class);

    public static void main(String[] args) {
        Activity activity = new Activity();
        Resources resources = activity.getResources();

        try {

            logger.info("main: origin:"+activity.getResources().mResourcesImpl);
            Class clazz = activity.getClass();
            while (clazz!=null){
                Field[] fields = clazz.getDeclaredFields();
                for (int i = 0; i < fields.length; i++) {
                    Field field = fields[i];

                    logger.info("main: field name:"+clazz+" "+field.getName());
                    if (field.getName().equals("mResources")){
                        field.setAccessible(true);
                        //todo 把值拿出来，为了还原。
                        Object o = field.get(activity);

                        logger.error("main: origin --->:"+activity.getResources().mResourcesImpl);

                        Resources res = new Resources();
                        res.mResourcesImpl = "mResourcesImpl modify";
                        field.set(activity, res);
                        logger.error("main: modify --->:"+activity.getResources().mResourcesImpl);

                        //还原 为原来的值
                        field.set(activity,o);
//                        origin.set(activity, o);// 与上一行一样。ok
                        logger.info("main: set origin-->:"+activity.getResources().mResourcesImpl);
                    }
                }
                clazz = clazz.getSuperclass();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

class Activity extends BaseActivity{
    String ActivityStr;
}

class BaseActivity extends ContextThemeWrapper{
    public String pubStr;
    String BaseActivityStr;
}

class ContextThemeWrapper{
    private Resources mResources;
    Resources getResources() {
        return getResourcesInternal();
    }
    private Resources getResourcesInternal() {
        if (mResources == null) {
            mResources = new Resources();
        }
        return mResources;
    }
}

class Resources{
    String mResourcesImpl = "default";
}